/*
Copyright 2010,2011 Matt Van Der Westhuizen

This file is part of CGLL.

CGLL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

CGLL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with CGLL.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.chaoticengine.cgll.entity.component.effects;

import org.chaoticengine.cgll.factory.ParticleEffectFactory;
import java.util.HashMap;
import org.chaoticengine.cgll.entity.component.ActiveRenderComponent;
import org.chaoticengine.cgll.entity.component.Command;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.particles.ParticleSystem;
import org.newdawn.slick.state.StateBasedGame;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

/**
 * Component to render a Slick2D particle effect attached to an entity.
 *
 * @author Matt Van Der Westhuizen <mattpwest@gmail.com>
 */
@Root
public class ParticleEffectComponent extends ActiveRenderComponent {
    protected int duration = 0;
    protected int timePassed = 0;
    protected Vector2f translation = new Vector2f();
    protected String psFilename = "";
    protected ParticleSystem ps = null;
    protected HashMap<String, Command> commands = new HashMap<String, Command>();
    protected boolean isDirectional = false;

    public ParticleEffectComponent() {}

    @Override
    public void onSetOwner() {
        super.onSetOwner();

        // Translate translation from % of object size to pixel values
        this.translation = new Vector2f(translation.x * owner.getBounds().getWidth(),
                translation.y * owner.getBounds().getHeight());
    }

    @Override
    public void update(GameContainer gc, StateBasedGame sb, int delta) {
        if ((ps != null) && (!isComplete())) {
            ps.update(delta);

            timePassed += delta;
        }
    }

    @Override
    public void render(GameContainer gc, StateBasedGame sb, Graphics gr) {
        if (ps != null) {
            Shape bounds = owner.getBounds();

            gr.translate(owner.getPosition().x, owner.getPosition().y);

            if (isDirectional) {
                gr.rotate(0.0f, 0.0f, getOwner().getRotation());
            }

            gr.translate(translation.x, translation.y);

            ps.render();

            gr.translate(-translation.x, -translation.y);

            if (isDirectional) {
                gr.rotate(0.0f, 0.0f, -getOwner().getRotation());
            }

            gr.translate(-owner.getPosition().x, -owner.getPosition().y);
        }
    }

    public HashMap<String, Command> getCommands() {
        return commands;
    }

    @Element(name="system")
    public String getSystem() {
        return psFilename;
    }

    @Element(name="system")
    public void setSystem(String filename) {
        this.psFilename = filename;

        try {
            ps = ParticleEffectFactory.getInstance().getEffect(filename);
        } catch (SlickException sEx) {
            System.out.println("Error: Failed to load particle system '" + filename + "'.");
            sEx.printStackTrace();
            System.exit(-1);
        }
    }

    @Element(name="translation", required=false)
    public Vector2f getTranslation() {
        return translation;
    }

    @Element(name="translation", required=false)
    public void setTranslation(Vector2f translation) {
        this.translation = translation;
    }

    @Element(name="duration", required=false)
    public int getDuration() {
        return(duration);
    }

    @Element(name="duration", required=false)
    public void setDuration(int d) {
        this.duration = d;
    }

    @Element(name="directional", required=false)
    public boolean isDirectional() {
        return isDirectional;
    }

    @Element(name="directional", required=false)
    public void setDirectional(boolean isDirectional) {
        this.isDirectional = isDirectional;
    }

    public int getTimePassed() {
        return(timePassed);
    }

    public boolean isComplete() {
        if (duration <= 0) {
            return(false);
        } else {
            return(timePassed >= duration);
        }
    }
}
